﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;

namespace BigExpedition
{
    public partial class MainForm : Form
    {
        const string LevelsListFilename = "levels.txt";
        string levelsDir = Application.StartupPath + @"\levels\";

        public MainForm()
        {
            InitializeComponent();
        }

        private List<string> getLevelsFilenames()
        {
            List<string> result = new List<string>();

            string levelFilePath = levelsDir + LevelsListFilename;

            if (!File.Exists(levelFilePath))
            {
                MessageBox.Show("File " + levelFilePath + " not found");
                return null;
            }

            using (TextReader reader = new StreamReader(levelFilePath))
            {
                while (reader.Peek() != -1)
                {
                    result.Add(reader.ReadLine());
                }
            }

            return result;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // получаем список всех уровней
            List<string> levelsFilenames = getLevelsFilenames();
            if (levelsFilenames == null) return;

            //foreach (string dllname in dllFiles)
            foreach (string levelFileName in levelsFilenames)
            {
                int formResult = 0;
                if (System.IO.File.Exists(levelsDir + levelFileName + ".dll"))
                {
                    Assembly assembly = Assembly.LoadFrom(levelsDir + levelFileName + ".dll");
             
                    Type[] types = assembly.GetTypes();


                    Type startType = null;
                    foreach (Type type in types)
                    {
                        if (type.FullName == levelFileName+".MyClass")
                        {
                            startType = type;
                            break;
                        }
                    }

                    // default ctor
                    ConstructorInfo constructor = startType.GetConstructor(Type.EmptyTypes);
                    if (constructor != null)
                    {
                        object instance = constructor.Invoke(new object[0]);
                        if (instance != null)
                        {
                            // only public instance methods
                            MethodInfo[] methods = instance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
                            if (methods.Length > 0)
                            {
                                // invoke only 1st method
                                ParameterInfo[] parameters = methods[0].GetParameters();
                                object[] inputParams = new object[parameters.Length];
                                int i = 0;
                                foreach (ParameterInfo parameter in parameters)
                                {
                                    //Type paramType = parameter.ParameterType;
                                    //if (paramType.Equals(typeof(int)))
                                    //{
                                    //    inputParams[i] = (int)50;
                                    //}
                                    //else if (paramType.Equals(typeof(short)))
                                    //{
                                    //    inputParams[i] = (short)5;
                                    //}

                                    // Here might be the endless check of possible parameters,
                                    // if you don't know anything about your type for example interfaces it implements or classes it inherits.

                                    i++;
                                }

                                object result = methods[0].Invoke(instance, inputParams);
                                if (result != null)
                                {
                                    formResult = (int)result;
                                }
                            }
                        }
                    }
                }
                // Если уровень не пройден, то следующий уровень не показываем
                if (formResult == 0) break;
            }
        }
    }
}
